package StudyCode.summary.BufferAndChannel;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 版权所有 科技与人文(www.tah1986.com)
 */
public class ThreeMemoryMappedBuffers {
	public static void main(String[] argv) throws Exception {
		File tempFile = File.createTempFile("test", null);
		RandomAccessFile file = new RandomAccessFile(tempFile, "rw");
		FileChannel channel = file.getChannel();
		ByteBuffer temp = ByteBuffer.allocate(100);

		temp.put("www.tah1986.com".getBytes());
		temp.flip();
		channel.write(temp, 0);

		temp.clear();
		temp.put("科技与人文".getBytes());
		temp.flip();
		channel.write(temp, 8192);

		MappedByteBuffer ro = channel.map(FileChannel.MapMode.READ_ONLY, 0,
				channel.size());
		MappedByteBuffer rw = channel.map(FileChannel.MapMode.READ_WRITE, 0,
				channel.size());
		MappedByteBuffer cow = channel.map(FileChannel.MapMode.PRIVATE, 0,
				channel.size());

		System.out.println("Begin");
		showBuffers(ro, rw, cow);
		cow.position(8);
		cow.put("test".getBytes());
		showBuffers(ro, rw, cow);
		rw.position(9);
		rw.put(" 11 ".getBytes());
		rw.position(8194);
		rw.put(" 22 ".getBytes());
		rw.force();
		showBuffers(ro, rw, cow);


		temp.clear();
		temp.put("Channel write ".getBytes());
		temp.flip();
		channel.write(temp, 0);
		temp.rewind();
		channel.write(temp, 8202);

		showBuffers(ro, rw, cow);
		cow.position(8207);
		cow.put(" COW2 ".getBytes());

		showBuffers(ro, rw, cow);

		rw.position(0);
		rw.put(" 22 ".getBytes());
		rw.position(8210);
		rw.put(" 22 ".getBytes());
		rw.force();

		showBuffers(ro, rw, cow);

		channel.close();
		file.close();
		tempFile.delete();
	}

	public static void showBuffers(ByteBuffer ro, ByteBuffer rw, ByteBuffer cow)
			throws Exception {
		dumpBuffer("R/O", ro);
		dumpBuffer("R/W", rw);
		dumpBuffer("COW", cow);
		System.out.println("");
	}

	public static void dumpBuffer(String prefix, ByteBuffer buffer)
			throws Exception {
		System.out.print(prefix + ": '");
		int nulls = 0;
		int limit = buffer.limit();
		for (int i = 0; i < limit; i++) {
			char c = (char) buffer.get(i);
			if (c == '\u0000') {
				nulls++;
				continue;
			}
			if (nulls != 0) {
				System.out.print("|[" + nulls + " nulls]|");
				nulls = 0;
			}
			System.out.print(c);
		}
		System.out.println("'");
	}
}
